library(quantstrat) library(data.table) library(dplyr) library(DT) library(ggplot2) library(htmltools) library(htmlwidgets) library(knitr) library(lattice) library(pander) library(tidyr) library(webshot) Sys.setenv(TZ = "UTC") currency('USD') init_date <- "2007-12-31" start_date <- "2008-01-01" end_date <- "2009-12-31" init_equity <- 1e4 adjustment <- TRUE basic_symbols <- function() { symbols <- c( "IWM", "QQQ", "SPY" ) } enhanced_symbols <- function() { symbols <- c( basic_symbols(), "TLT", "XLB", "XLE", "XLF", "XLI", "XLK", "XLP", "XLU", "XLV", "XLY" ) } global_symbols <- function() { symbols <- c( enhanced_symbols(), "EFA", "EPP", "EWA", "EWC", "EWG", "EWH", "EWJ", "EWS", "EWT", "EWU", "EWY", "EWZ", "EZU", "IGE", "IYR", "IYZ", "LQD", "SHY" ) } checkBlotterUpdate <- function(port.st = portfolio.st, account.st = account.st, verbose = TRUE) { ok <- TRUE p <- getPortfolio(port.st) a <- getAccount(account.st) syms <- names(p$symbols) port.tot <- sum( sapply( syms, FUN = function(x) eval( parse( text = paste("sum(p$symbols", x, "posPL.USD$Net.Trading.PL)", sep = "$"))))) port.sum.tot <- sum(p$summary$Net.Trading.PL) if(!isTRUE(all.equal(port.tot, port.sum.tot))) { ok <- FALSE if(verbose) print("portfolio P&L doesn't match sum of symbols P&L") } initEq <- as.numeric(first(a$summary$End.Eq)) endEq <- as.numeric(last(a$summary$End.Eq)) if(!isTRUE(all.equal(port.tot, endEq - initEq)) ) { ok <- FALSE if(verbose) print("portfolio P&L doesn't match account P&L") } if(sum(duplicated(index(p$summary)))) { ok <- FALSE if(verbose)print("duplicate timestamps in portfolio summary") } if(sum(duplicated(index(a$summary)))) { ok <- FALSE if(verbose) print("duplicate timestamps in account summary") } return(ok) } print(basic_symbols()) symbols <- basic_symbols() getSymbols(Symbols = symbols, src = "google", index.class = "POSIXct", from = start_date, to = end_date, adjust = adjustment) head(IWM) tail(IWM) chartSeries(SPY) stock(symbols, currency = "USD", multiplier = 1) portfolio.st <- "Port.Luxor" account.st <- "Acct.Luxor" strategy.st <- "Strat.Luxor" rm.strat(portfolio.st) rm.strat(account.st) initPortf(name = portfolio.st, symbols = symbols, initDate = init_date) initAcct(name = account.st, portfolios = portfolio.st, initDate = init_date, initEq = init_equity) initOrders(portfolio = portfolio.st, symbols = symbols, initDate = init_date) strategy(strategy.st, store = TRUE) add.indicator(strategy = strategy.st, name = "SMA", arguments = list(x = quote(Cl(mktdata)), n = 10), label = "nFast") add.indicator(strategy = strategy.st, name = "SMA", arguments = list(x = quote(Cl(mktdata)), n = 30), label = "nSlow") add.signal(strategy = strategy.st, name="sigCrossover", arguments = list(columns = c("nFast", "nSlow"), relationship = "gte"), label = "long") add.signal(strategy = strategy.st, name="sigCrossover", arguments = list(columns = c("nFast", "nSlow"), relationship = "lt"), label = "short") add.rule(strategy = strategy.st, name = "ruleSignal", arguments = list(sigcol = "long", sigval = TRUE, orderqty = 100, ordertype = "stoplimit", orderside = "long", threshold = 0.0005, prefer = "High", TxnFees = -10, replace = FALSE), type = "enter", label = "EnterLONG") add.rule(strategy.st, name = "ruleSignal", arguments = list(sigcol = "short", sigval = TRUE, orderqty = -100, ordertype = "stoplimit", threshold = -0.005, orderside = "short", replace = FALSE, TxnFees = -10, prefer = "Low"), type = "enter", label = "EnterSHORT") add.rule(strategy.st, name = "ruleSignal", arguments = list(sigcol = "short", sigval = TRUE, orderside = "long", ordertype = "market", orderqty = "all", TxnFees = -10, replace = TRUE), type = "exit", label = "Exit2SHORT") add.rule(strategy.st, name = "ruleSignal", arguments = list(sigcol = "long", sigval = TRUE, orderside = "short", ordertype = "market", orderqty = "all", TxnFees = -10, replace = TRUE), type = "exit", label = "Exit2LONG") cwd <- getwd() setwd("./_data/") results_file <- paste("results", strategy.st, "RData", sep = ".") if( file.exists(results_file) ) { load(results_file) } else { results <- applyStrategy(strategy.st, portfolios = portfolio.st) updatePortf(portfolio.st) updateAcct(account.st) updateEndEq(account.st) if(checkBlotterUpdate(portfolio.st, account.st, verbose = TRUE)) { save(list = "results", file = results_file) save.strategy(strategy.st) } } setwd(cwd) checkBlotterUpdate(portfolio.st, account.st, verbose = TRUE) updatePortf(portfolio.st) updateAcct(account.st) updateEndEq(account.st) for(symbol in symbols) { chart.Posn(portfolio.st, Symbol = symbol, TA = "add_SMA(n = 10, col = 4); add_SMA(n = 30, col = 2)") } tstats <- tradeStats(portfolio.st) kable(t(tstats)) tab.trades <- tstats %>% mutate(Trades = Num.Trades, Win.Percent = Percent.Positive, Loss.Percent = Percent.Negative, WL.Ratio = Percent.Positive/Percent.Negative) %>% select(Trades, Win.Percent, Loss.Percent, WL.Ratio) rownames(tab.trades)=c('stock1','stock2','stock3') kable(t(tab.trades)) tab.profit <- tstats %>% select(Net.Trading.PL, Gross.Profits, Gross.Losses, Profit.Factor) kable(t(tab.profit)) tab.wins <- tstats %>% select(Avg.Trade.PL, Avg.Win.Trade, Avg.Losing.Trade, Avg.WinLoss.Ratio) kable(t(tab.wins)) rets <- PortfReturns(Account = account.st) rownames(rets) <- NULL charts.PerformanceSummary(rets, colorset = bluefocus) for(symbol in symbols) { pts <- perTradeStats(portfolio.st, Symbol = symbol) kable(pts, booktabs = TRUE, caption = symbol) } kable(pts) tab.perf <- table.Arbitrary(rets, metrics=c( "Return.cumulative", "Return.annualized", "SharpeRatio.annualized", "CalmarRatio"), metricsNames=c( "Cumulative Return", "Annualized Return", "Annualized Sharpe Ratio", "Calmar Ratio")) kable(tab.perf) tab.risk <- table.Arbitrary(rets, metrics=c( "StdDev.annualized", "maxDrawdown", "VaR", "ES"), metricsNames=c( "Annualized StdDev", "Max DrawDown", "Value-at-Risk", "Conditional VaR")) kable(tab.risk) rm.strat("buyHold") initPortf("buyHold", "SPY", initDate = init_date) initAcct("buyHold", portfolios = "buyHold", initDate = init_date, initEq = init_equity) CurrentDate <- time(getTxns(Portfolio = portfolio.st, Symbol = "SPY"))[2] equity = getEndEq("buyHold", CurrentDate) ClosePrice <- as.numeric(Cl(SPY[CurrentDate,])) UnitSize = as.numeric(trunc(equity/ClosePrice)) addTxn("buyHold", Symbol = "SPY", TxnDate = CurrentDate, TxnPrice = ClosePrice, TxnQty = UnitSize, TxnFees = 0) LastDate <- last(time(SPY)) LastPrice <- as.numeric(Cl(SPY[LastDate,])) addTxn("buyHold", Symbol = "SPY", TxnDate = LastDate, TxnPrice = LastPrice, TxnQty = -UnitSize , TxnFees = 0) updatePortf(Portfolio = "buyHold") updateAcct(name = "buyHold") updateEndEq(Account = "buyHold") chart.Posn("buyHold", Symbol = "SPY") rets <- PortfReturns(Account = account.st) rets.bh <- PortfReturns(Account = "buyHold") returns <- cbind(rets, rets.bh) charts.PerformanceSummary(returns, geometric = FALSE, wealth.index = TRUE, main = "Strategy vs. Market") chart.RiskReturnScatter(returns, Rf = 0, add.sharpe = c(1, 2), main = "Return vs. Risk", colorset = c("red", "blue")) for(n in 1:(ncol(returns) - 1)) { chart.RelativePerformance(returns[, n], returns[, ncol(returns)], colorset = c("red", "blue"), lwd = 2, legend.loc = "topleft") } pf <- getPortfolio(portfolio.st) xyplot(pf$summary, type = "h", col = 4) ob <- getOrderBook(portfolio.st) for(symbol in symbols) { chart.ME(Portfolio = portfolio.st, Symbol = symbol, type = "MAE", scale = "percent") } for(symbol in symbols) { chart.ME(Portfolio = portfolio.st, Symbol = symbol, type = "MFE", scale = "percent") } a <- getAccount(account.st) xyplot(a$summary, type = "h", col = 4) equity <- a$summary$End.Eq plot(equity, main = "Equity Curve") ret <- Return.calculate(equity, method = "log") charts.PerformanceSummary(ret, colorset = bluefocus, main = "Strategy Performance") rets <- PortfReturns(Account = account.st) chart.CumReturns(rets, colorset = rich10equal, legend.loc = "topleft", main="SPDR Cumulative Returns") chart.Boxplot(rets, main = "SPDR Returns", colorset= rich10equal) (ar.tab <- table.AnnualizedReturns(rets)) max.risk <- max(ar.tab["Annualized Std Dev",]) max.return <- max(ar.tab["Annualized Return",]) chart.RiskReturnScatter(rets, main = "SPDR Performance", colorset = rich10equal, xlim = c(0, max.risk * 1.1), ylim = c(0, max.return))
|